/**
 * 使用C++模拟实现vector
 */
#pragma once
#include <iostream>
#include <cassert>
#define VECTORSIZE 5
namespace myVector
{
    template <class T>
    class Vector
    {
    public:
        using iterator = T *;

    public:
        Vector()
            : _begin(nullptr), _end(nullptr), _capacity(nullptr)
        {
            // 最开始就留有一定的空间，防止来回申请，效率低下
            _begin = new T[VECTORSIZE];
            _end = _begin;
            _capacity = _begin + VECTORSIZE; // 更新容量指针到最大容量位置
        }

        Vector(int n, const T &value = T())
            : _begin(nullptr), _end(nullptr), _capacity(nullptr)
        {
            resize(n, value);
        }

        const Vector<T> &operator=(const Vector<T> &another)
        {
            if (this != &another)
            {
                reserve(another.capacity());
                iterator my_help = _begin;
                iterator another_help = another.begin();
                while (another_help < another.end())
                {
                    *my_help = *another_help;
                    ++my_help;
                    ++another_help;
                }
            }
            return *this;
        }

        ~Vector()
        {
            if (_begin != nullptr)
            {
                delete[] _begin;
                _begin = nullptr;
                _end = nullptr;
                _capacity = nullptr;
            }
        }

        // 增删查改

        // 增
        void insert(iterator pos, const T &value)
        {
            assert(pos >= _begin && pos <= _end); // 插入的位置应该在有效范围内

            // 满了，要扩容
            if (_end == _capacity)
            {
                std::cout << "扩容啦" << std::endl;
                reserve(2 * capacity());
                // std::cout << "扩容后的vecotr " << std::endl;
                // for (iterator help = begin(); help < end(); ++help)
                // {
                //     std::cout << *help << " ";
                // }
                // std::cout << std::endl;
            }

            // 没满，可以继续插入
            iterator help = _end;
            pos = _end;
            // 向后移动数据
            for (; help > pos; --help)
            {
                *help = *(help - 1);
            }

            *pos = value;
            // std::cout << "&pos = " << pos << std::endl;
            // std::cout << "*pos = " << *pos << std::endl;
            // std::cout << "&end = " << _end << std::endl;
            // std::cout << "*_end = " << *_end << std::endl;
            ++_end;
        }
        // 尾插
        void push_back(const T &value) { insert(end(), value); }
        // 头插
        void push_front(const T &value) { insert(begin(), value); }

        // 删
        void erase(iterator pos)
        {
            assert(_begin != _end);             // vector不能为空
            assert(pos >= _begin && pos < _end); // 删除的位置应该在有效范围内

            iterator help = pos;
            while (help < _end - 1)
            {
                *help = *(help + 1);
                ++help;
            }
            *help = 0;
            --_end;
        }
        // 尾删
        void pop_back() { erase(_end - 1); }
        // 头删
        void pop_front() { erase(_begin); }
        // 清空所有数据
        void clear() { _end = _begin; }

        // 有效数据个数
        int size() { return (_end - _begin) / sizeof(T); }
        // 实际容量大小
        int capacity() { return (_capacity - _begin) / sizeof(T); }

        // 预设置有效数据
        void resize(int n, const T &value = T())
        {
            // n > capacity 需要扩容
            if (n > capacity())
            {
                reserve(n);
            }
            // n <= capacity 直接设置
            _begin = new T[n];
            iterator help = _begin;
            for (int i = 0; i < n; ++i)
            {
                *help = value;
                ++help;
            }
            _end = help;
        }

        // 预设置容量
        void reserve(int capa)
        {
            if (capa < size())
            {
                _end = _begin + capa;
                _capacity = _begin + capa;
            }
            else if (capa >= size() && capa <= capacity())
            {
                _capacity = _begin + capa;
            }
            else if (capa > capacity())
            {
                // 异地扩容
                iterator new_begin = nullptr;
                iterator new_end = nullptr;
                iterator new_capacity = nullptr;
                new_begin = new T[capa];
                new_end = new_begin;
                new_capacity = new_begin + capa;

                iterator help = _begin;
                while (help < _end)
                {
                    *new_end = *help;
                    ++new_end;
                    ++help;
                }
                // help = new_begin;
                // std::cout << "异地扩容后的内容" << std::endl;
                // for(;help < new_end; ++help)
                // {
                //     std::cout << *help << " ";
                // }
                // std::cout << std::endl;

                delete[] _begin;
                _begin = new_begin;
                _end = new_end;
                _capacity = new_capacity;
            }
        }

        // 是否为空
        bool empty() { return _begin == _end; }

        T &operator[](int pos)
        {
            assert(pos > -1);
            assert(pos < size());

            return *(_begin + pos);
        }

        iterator& begin() { return _begin; }
        iterator& end() { return _end; }

    private:
        // 设计vector的成员变量，首先要明确vector的特性：动态开辟的数组，可以扩容缩容
        // 所以我们选择使用pointer实现
        iterator _begin;    // vector第一个元素的地址
        iterator _end;      // vector最后一个元素的下一个地址
        iterator _capacity; // vecotr最后一个空间的下一个地址
    };
}